import os
import subprocess
from datetime import datetime
from src.modules.ffmpeg_command_builder import FFmpegCommandBuilder
from src.modules.file_manager import FileManager
from src.utils.logger import log_info, log_error
from src.modules.media_processor import MediaProcessor

class VideoEffectProcessor:
    """处理视频效果，包括淡入淡出、过渡和其他特效"""
    
    def __init__(self, startupinfo=None, logger=None):
        """初始化视频效果处理器
        
        :param startupinfo: 用于subprocess的startupinfo对象，默认为None
        :param logger: 用于日志记录的函数，默认为None
        """
        self.startupinfo = startupinfo
        self.logger = logger
        self.media_processor = MediaProcessor(startupinfo=startupinfo, logger=logger)
        self.file_manager = FileManager(logger=logger)
    
    def _log_info(self, message):
        """记录信息级别日志"""
        if self.logger:
            self.logger(message)
        else:
            from src.utils.logger import log_info
            log_info(message)
    
    def _log_error(self, message):
        """记录错误级别日志"""
        if self.logger:
            self.logger(message, level="error")
        else:
            from src.utils.logger import log_error
            log_error(message)
    
    # 原有的淡入淡出方法保留
    def apply_video_fade_out(self, video_path, output_path=None, fade_duration=1.0):
        """为视频添加淡出效果 - 使用新的FFmpegCommandBuilder
        
        :param video_path: 视频文件路径
        :param output_path: 输出视频路径，如果为None则自动生成
        :param fade_duration: 淡出效果持续时间（秒）
        :return: dict: 处理结果
        """
        try:
            # 获取视频时长
            video_duration = self.media_processor.get_media_duration(video_path)
            if video_duration is None:
                return {"success": False, "message": "无法获取视频时长"}
                
            # 计算淡出开始时间
            fade_start = max(0, video_duration - fade_duration)
            
            # 创建输出路径
            if output_path is None:
                base_name = os.path.basename(video_path)
                name, ext = os.path.splitext(base_name)
                temp_file = self.file_manager.create_temp_file(
                    prefix=f"{name}_",
                    suffix=f"_fadeout{ext}",
                    category="video_effects"
                )
                output_path = temp_file.path
            else:
                # 确保输出路径有正确的扩展名
                if not os.path.splitext(output_path)[1]:
                    # 如果没有扩展名，添加与输入文件相同的扩展名
                    _, ext = os.path.splitext(video_path)
                    output_path = output_path + ext
                    
            self._log_info(f"添加淡出效果，输出路径: {output_path}")
            
            # 使用FFmpegCommandBuilder构建和执行命令
            result = FFmpegCommandBuilder(self.startupinfo, self.logger) \
                .add_input(video_path) \
                .add_video_filter(f"fade=t=out:st={fade_start}:d={fade_duration}:color=black") \
                .add_audio_filter(f"afade=t=out:st={fade_start}:d={fade_duration}") \
                .set_video_codec("libx264", "medium", 18) \
                .set_audio_codec("aac", "192k") \
                .add_output(output_path) \
                .execute("添加视频淡出效果", check=False)
            
            if result["success"]:
                self._log_info(f"视频淡出效果添加成功: {output_path}")
                import time
                time.sleep(0.2)  # 确保文件系统有时间更新
                return {"success": True, "output_path": output_path}
            else:
                self._log_error(f"添加淡出效果失败: {result['message']}")
                return {"success": False, "message": result["message"]}
                
        except Exception as e:
            self._log_error(f"添加淡出效果时出错: {str(e)}")
            return {"success": False, "message": f"添加淡出效果时出错: {str(e)}"}
    
    def apply_audio_fade_out(self, audio_path, output_path=None, fade_duration=1.0):
        """为音频添加淡出效果 - 使用新的FFmpegCommandBuilder
        
        :param audio_path: 音频文件路径
        :param output_path: 输出音频路径，如果为None则自动生成
        :param fade_duration: 淡出效果持续时间（秒）
        :return: dict: 处理结果
        """
        try:
            # 获取音频时长
            audio_duration = self.media_processor.get_media_duration(audio_path)
            if audio_duration is None:
                return {"success": False, "message": "无法获取音频时长"}
                
            # 计算淡出开始时间
            fade_start = max(0, audio_duration - fade_duration)
            
            # 创建输出路径
            if output_path is None:
                base_name = os.path.basename(audio_path)
                name, ext = os.path.splitext(base_name)
                temp_file = self.file_manager.create_temp_file(
                    prefix=f"{name}_",
                    suffix=f"_fadeout{ext}",
                    category="audio_effects"
                )
                output_path = temp_file.path
                
            self._log_info(f"添加音频淡出效果，开始时间: {fade_start}秒，持续: {fade_duration}秒")
            
            # 使用FFmpegCommandBuilder构建和执行命令
            result = FFmpegCommandBuilder(self.startupinfo, self.logger) \
                .add_input(audio_path) \
                .add_audio_filter(f"afade=t=out:st={fade_start}:d={fade_duration}") \
                .set_audio_codec("aac", "192k") \
                .add_output(output_path) \
                .execute("添加音频淡出效果", check=False)
            
            if result["success"]:
                self._log_info(f"音频淡出效果添加成功: {output_path}")
                return {"success": True, "output_path": output_path}
            else:
                self._log_error(f"添加音频淡出效果失败: {result['message']}")
                return {"success": False, "message": f"添加音频淡出效果失败: {result['message']}"}
                
        except Exception as e:
            self._log_error(f"添加音频淡出效果时出错: {str(e)}")
            return {"success": False, "message": f"添加音频淡出效果时出错: {str(e)}"}
    
    # 新增方法 - 从VideoMerger迁移过来
    def apply_transition_effect(self, videos, output_path, transition_effect="fade", transition_duration=1.0):
        """为多个视频添加过渡效果
        
        :param videos: 视频文件路径列表
        :param output_path: 输出视频路径
        :param transition_effect: 过渡效果类型
        :param transition_duration: 过渡效果持续时间（秒）
        :return: dict: 处理结果
        """
        try:
            if len(videos) < 2:
                self._log_info("视频数量不足，无法应用过渡效果")
                return {"success": False, "message": "视频数量不足，无法应用过渡效果"}
                
            # 获取每个视频的信息
            video_info = []
            for i, video_path in enumerate(videos):
                info = {}
                # 获取视频分辨率
                resolution = self.media_processor.get_video_resolution(video_path)
                if resolution:
                    info['resolution'] = resolution
                    self._log_info(f"视频 #{i+1} 分辨率: {resolution[0]}x{resolution[1]}")
                else:
                    return {"success": False, "message": f"无法获取视频 #{i+1} 分辨率"}
                
                # 获取视频时长
                duration = self.media_processor.get_media_duration(video_path)
                if duration is not None:
                    info['duration'] = duration
                    self._log_info(f"视频 #{i+1} 时长: {duration}秒")
                    
                    # 检查过渡效果是否适合视频长度
                    if transition_effect and duration < transition_duration * 1.5:
                        self._log_info(f"警告: 视频 #{i+1} 时长({duration}秒)不足以支持 {transition_duration}秒 的过渡")
                else:
                    return {"success": False, "message": f"无法获取视频 #{i+1} 时长"}
                
                # 检查音频流
                has_audio_stream = self.media_processor.has_audio_stream(video_path)
                info['has_audio'] = has_audio_stream
                self._log_info(f"视频 #{i+1} 音频: {'有' if has_audio_stream else '无'}")
                
                video_info.append(info)
            
            # 计算最大分辨率作为目标分辨率
            target_width = max(info['resolution'][0] for info in video_info)
            target_height = max(info['resolution'][1] for info in video_info)
            self._log_info(f"目标分辨率设置为: {target_width}x{target_height} (最大宽高)")
            
            # 创建FFmpeg命令构建器
            cmd_builder = FFmpegCommandBuilder(self.startupinfo, self.logger)
            
            # 添加所有输入视频
            for video_path in videos:
                cmd_builder.add_input(video_path)
            
            # 构建复杂滤镜表达式
            filter_complex = []
            
            # 为每个视频添加标准化处理滤镜
            for i in range(len(videos)):
                filter_part = f"[{i}:v]fps=30,scale={target_width}:{target_height}:force_original_aspect_ratio=decrease," + \
                             f"pad={target_width}:{target_height}:(ow-iw)/2:(oh-ih)/2,setsar=1:1,format=yuv420p[v{i}];"
                filter_complex.append(filter_part)
                
                # 音频处理部分
                if video_info[i]['has_audio']:
                    audio_part = f"[{i}:a]aformat=sample_rates=44100:channel_layouts=stereo[a{i}];"
                    filter_complex.append(audio_part)
                else:
                    # 为没有音频的视频生成静音轨道
                    audio_part = f"anullsrc=r=44100:cl=stereo:d={video_info[i]['duration']}[a{i}];"
                    filter_complex.append(audio_part)
            
            # 使用过渡效果进行合并
            if transition_effect and len(videos) >= 2:
                # 处理第一对视频 - 动态计算offset
                first_offset = max(0, video_info[0]['duration'] - transition_duration)
                first_transition = f"[v0][v1]xfade=transition={transition_effect}:duration={transition_duration}:offset={first_offset}[vtmp1];"
                filter_complex.append(first_transition)
                
                # 累计视频长度，用于计算后续过渡的offset
                cumulative_duration = video_info[0]['duration'] + video_info[1]['duration'] - transition_duration
                
                # 处理剩余视频
                for i in range(2, len(videos)):
                    next_offset = max(0, cumulative_duration - transition_duration)
                    next_transition = f"[vtmp{i-1}][v{i}]xfade=transition={transition_effect}:duration={transition_duration}:offset={next_offset}[vtmp{i}];"
                    filter_complex.append(next_transition)
                    
                    # 更新累计时长
                    cumulative_duration += video_info[i]['duration'] - transition_duration
                
                # 处理音频 - 合并所有音频流
                audio_streams = "".join([f"[a{i}]" for i in range(len(videos))])
                audio_concat = f"{audio_streams}concat=n={len(videos)}:v=0:a=1:unsafe=1[aout]"
                filter_complex.append(audio_concat)
                
                # 设置输出映射
                final_video = f"[vtmp{len(videos)-1}]"
                final_audio = "[aout]"
            else:
                # 使用简单concat
                v_streams = "".join([f"[v{i}]" for i in range(len(videos))])
                a_streams = "".join([f"[a{i}]" for i in range(len(videos))])
                
                video_concat = f"{v_streams}concat=n={len(videos)}:v=1:a=0:unsafe=1[vout];"
                audio_concat = f"{a_streams}concat=n={len(videos)}:v=0:a=1:unsafe=1[aout];"
                
                filter_complex.append(video_concat)
                filter_complex.append(audio_concat)
                
                # 设置输出映射
                final_video = "[vout]"
                final_audio = "[aout]"
            
            # 将构建好的复杂滤镜添加到命令中
            cmd_builder.add_filter_complex(";".join(filter_complex))
            
            # 添加输出映射
            cmd_builder.add_map(final_video)
            cmd_builder.add_map(final_audio)
            
            # 设置编码参数
            cmd_builder.set_video_codec("libx264", "medium", 23)
            cmd_builder.set_audio_codec("aac", "192k")
            
            # 添加其他参数
            cmd_builder.add_global_option("-profile:v", "main")
            cmd_builder.add_global_option("-level", "4.0")
            cmd_builder.add_global_option("-ar", "44100")
            cmd_builder.add_global_option("-movflags", "+faststart")
            cmd_builder.add_global_option("-max_muxing_queue_size", "1024")
            
            # 设置输出
            cmd_builder.add_output(output_path)
            
            # 执行命令
            self._log_info(f"开始执行ffmpeg过渡合并命令...")
            result = cmd_builder.execute("视频过渡合并")
            
            if result["success"]:
                self._log_info(f"过渡效果应用成功: {output_path}")
                return {"success": True, "output_path": output_path}
            else:
                self._log_error(f"应用过渡效果失败: {result['message']}")
                return {"success": False, "message": result["message"]}
                
        except Exception as e:
            error_message = f"应用过渡效果时出错: {str(e)}"
            self._log_error(error_message)
            import traceback
            self._log_error(traceback.format_exc())
            return {"success": False, "message": error_message}

    def get_available_transition_effects(self):
        """获取所有可用的过渡效果
        
        :return: 包含过渡效果信息的列表
        """
        return [
            { "id": "fade", "name": "Fade", "description": "淡入淡出效果，常用于视频开头或结尾" },
            { "id": "wipeleft", "name": "Wipe Left", "description": "从右向左滑动过渡" },
            { "id": "wiperight", "name": "Wipe Right", "description": "从左向右滑动过渡" },
            { "id": "wipeup", "name": "Wipe Up", "description": "从下往上滑动过渡" },
            { "id": "wipedown", "name": "Wipe Down", "description": "从上往下滑动过渡" },
            { "id": "slideleft", "name": "Slide Left", "description": "旧画面向左滑出，新画面滑入" },
            { "id": "slideright", "name": "Slide Right", "description": "旧画面向右滑出，新画面滑入" },
            { "id": "slideup", "name": "Slide Up", "description": "旧画面向上滑出，新画面滑入" },
            { "id": "slidedown", "name": "Slide Down", "description": "旧画面向下滑出，新画面滑入" },
            { "id": "circlecrop", "name": "Circle Crop", "description": "以圆形裁剪方式切换" },
            { "id": "rectcrop", "name": "Rectangle Crop", "description": "以矩形裁剪方式切换" },
            { "id": "distance", "name": "Distance", "description": "通过缩小拉远实现过渡" },
            { "id": "fadeblack", "name": "Fade to Black", "description": "渐变至黑色再切换" },
            { "id": "fadewhite", "name": "Fade to White", "description": "渐变至白色再切换" },
            { "id": "radial", "name": "Radial", "description": "放射状过渡效果" },
            { "id": "smoothleft", "name": "Smooth Left", "description": "平滑左移效果" },
            { "id": "smoothright", "name": "Smooth Right", "description": "平滑右移效果" },
            { "id": "smoothup", "name": "Smooth Up", "description": "平滑上移效果" },
            { "id": "smoothdown", "name": "Smooth Down", "description": "平滑下移效果" },
            { "id": "circleopen", "name": "Circle Open", "description": "圆形打开效果" },
            { "id": "circleclose", "name": "Circle Close", "description": "圆形关闭效果" },
            { "id": "vertopen", "name": "Vertical Open", "description": "从中间垂直展开" },
            { "id": "vertclose", "name": "Vertical Close", "description": "从两边垂直关闭" },
            { "id": "horzopen", "name": "Horizontal Open", "description": "从中间水平展开" },
            { "id": "horzclose", "name": "Horizontal Close", "description": "从两边水平关闭" },
            { "id": "dissolve", "name": "Dissolve", "description": "通过像素随机透明实现溶解过渡" },
            { "id": "pixelize", "name": "Pixelize", "description": "通过像素化图像进行过渡" },
            { "id": "diagtl", "name": "Diagonal Top Left", "description": "从左上对角线方向切换" },
            { "id": "diagtr", "name": "Diagonal Top Right", "description": "从右上对角线方向切换" },
            { "id": "diagbl", "name": "Diagonal Bottom Left", "description": "从左下对角线方向切换" },
            { "id": "diagbr", "name": "Diagonal Bottom Right", "description": "从右下对角线方向切换" },
            { "id": "hlslice", "name": "Horizontal Left Slice", "description": "水平从左向右切片切换" },
            { "id": "hrslice", "name": "Horizontal Right Slice", "description": "水平从右向左切片切换" },
            { "id": "vuslice", "name": "Vertical Up Slice", "description": "垂直从下向上切片切换" },
            { "id": "vdslice", "name": "Vertical Down Slice", "description": "垂直从上向下切片切换" },
            { "id": "hblur", "name": "Horizontal Blur", "description": "通过水平模糊实现过渡" },
            { "id": "wipetl", "name": "Wipe Top Left", "description": "从左上角擦除切换" },
            { "id": "wipetr", "name": "Wipe Top Right", "description": "从右上角擦除切换" },
            { "id": "wipebl", "name": "Wipe Bottom Left", "description": "从左下角擦除切换" },
            { "id": "wipebr", "name": "Wipe Bottom Right", "description": "从右下角擦除切换" },
            { "id": "squeezeh", "name": "Squeeze Horizontal", "description": "水平收缩切换" },
            { "id": "squeezev", "name": "Squeeze Vertical", "description": "垂直收缩切换" },
            { "id": "zoom", "name": "Zoom", "description": "通过缩放实现场景切换" },
            { "id": "crossfade", "name": "Cross Fade", "description": "交叉淡入淡出，两个场景平滑过渡" },
            { "id": "push", "name": "Push", "description": "新画面推动旧画面切换" }
        ]